/**
 * Copyright (c) 2008 Trent Hoeppner
 * 
 * This file is part of BillCalc.
 * 
 * BillCalc is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * BillCalc is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with BillCalc.  If not, see <http://www.gnu.org/licenses/>.
 **/

package com.trentech.billcalc.event;

import java.util.Date;

import testcases.MainTest;

import com.trentech.billcalc.FinanceManager;


/**
 * SetupBillEvent is used to configure a Biller.
 * 
 * @author Trent Hoeppner
 */
public class SetupBillEvent extends Event {

    /**
     * True if the bill does not change between bills, false if it depends on 
     * usage.
     */
    private boolean fixedCost;
    
    
    /**
     * True if the bill comes after consumption, false if it comes before 
     * consumption.
     */
    private boolean afterConsumption;


    /**
     * Constructor for SetupBillEvent.
     * 
     * @param   date                the date that the bill is setup.  Cannot be 
     *                              null.
     * @param   name                the name of the bill to setup.  Cannot be 
     *                              null or empty.
     * @param   fixedCost           true if the bill does not change every 
     *                              month, false if it depends on usage.
     * @param   afterConsumption    true if the bill comes after consumption, 
     *                              false if the bill comes before consumption.
     */
    public SetupBillEvent(Date date, String name, boolean fixedCost, 
            boolean afterConsumption) {
        super(date, name);
        
        this.fixedCost = fixedCost;
        this.afterConsumption = afterConsumption;
    }


    /**
     * {@inheritDoc}
     */
    public int compareTo(Event other) {
        int value = super.compareTo(other);
        if (value != 0) {
            return value;
        }
        
        SetupBillEvent otherCasted = (SetupBillEvent) other;
        value = boolToValue(fixedCost) - boolToValue(otherCasted.isFixedCost());
        if (value != 0) {
            return value;
        }
        
        value = boolToValue(afterConsumption) - boolToValue(otherCasted.isAfterConsumption());
        if (value != 0) {
            return value;
        }
        
        return 0;
    }
    
    
    /**
     * {@inheritDoc}
     */
    public void process(FinanceManager manager) {
        manager.setupBill(getName(), fixedCost, afterConsumption);
    }


    /**
     * Returns whether the bill is fixed cost.
     * 
     * @return  true if the bill is fixed cost, false if it is variable cost.
     */
    public boolean isFixedCost() {
    	// original : 
        // return fixedCost;
    	// seed fault : 
    	return MainTest.isOriginal || MainTest.isFaultFound ? fixedCost : (fixedCost && false);
    }


    /**
     * Sets whether the bill is fixed cost.
     * 
     * @param   fixedCost   true indicates that the bill is fixed cost, false 
     *                      indicates that the bill is variable cost.
     */
    public void setFixedCost(boolean fixedCost) {
        this.fixedCost = fixedCost;
    }


    /**
     * Returns whether the bill is charged after consumption of the service or 
     * product (past Residents should pay), or before (future Residents should 
     * pay).
     *  
     * @return  true if the bill comes after consumption, false if it comes 
     *          before consumption.
     */
    public boolean isAfterConsumption() {
        return afterConsumption;
    }


    /**
     * Sets whether the bill is charged before or after consumption.
     * 
     * @param   afterConsumption    true if the bill comes after consumption, 
     *                              false if the bill comes before consumption.
     *                              
     * @see SetupBillEvent#isAfterConsumption()
     */
    public void setAfterConsumption(boolean afterConsumption) {
        this.afterConsumption = afterConsumption;
    }
}
